package com.yc.testupload.util;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;

/**
 * 数据库连接工具类
 * 提供数据库连接的获取、关闭和配置重新加载功能
 */
public class DatabaseUtil {

    private static final Logger logger = LogManager.getLogger(DatabaseUtil.class);
    private static volatile Properties properties = new Properties();

    /**
     * 获取数据库配置属性
     * 
     * @return 配置Properties对象
     */
    public static Properties getProperties() {
        return properties;
    }

    private static DataSource dataSource;
    private static EnvironmentManager environmentManager;

    // 静态初始化块，加载数据库配置
    static {
        try {
            // 获取环境管理器
            environmentManager = EnvironmentManager.getInstance();
            String currentEnv = environmentManager.getCurrentEnvironment();

            // 使用EnvironmentManager加载当前环境的配置
            properties = environmentManager.getCurrentDatabaseConfig();
            logger.info("DatabaseUtil: 加载环境: {}, 数据库配置已加载，包含{}个配置项",
                    currentEnv, properties.size());

            // 记录关键配置信息（不记录密码）
            if (properties != null && !properties.isEmpty()) {
                String jdbcUrl = properties.getProperty("jdbc.url");
                String username = properties.getProperty("jdbc.username");
                logger.info("DatabaseUtil: 数据库URL: {}, 用户名: {}", jdbcUrl, username);
            }

            // 尝试注册驱动
            try {
                String driver = properties.getProperty("driver", properties.getProperty("jdbc.driver"));
                Class.forName(driver);
                logger.info("成功注册JDBC驱动: {}", driver);
            } catch (ClassNotFoundException e) {
                logger.error("无法加载JDBC驱动: {}", e.getMessage());
            }
        } catch (Exception e) {
            logger.error("加载数据库配置文件失败: {}", e.getMessage());
            // 如果环境配置加载失败，尝试加载默认配置作为后备
            try (InputStream input = DatabaseUtil.class.getClassLoader().getResourceAsStream("database.properties")) {
                if (input != null) {
                    properties.load(input);
                    logger.info("成功加载默认数据库配置文件");
                } else {
                    logger.error("找不到默认的database.properties配置文件");
                }
            } catch (IOException ex) {
                logger.error("加载默认数据库配置文件失败: {}", ex.getMessage());
            }
        }
    }

    /**
     * 获取数据库连接（直接方式）
     * 
     * @return 数据库连接对象
     */
    public static Connection getConnection() throws SQLException {
        Connection conn = null;
        try {
            // 如果配置为空，尝试重新加载配置
            if (properties == null || properties.isEmpty()) {
                logger.warn("配置为空，尝试重新加载配置");
                reloadConfiguration();
            }

            // 尝试获取无前缀的键名，如果没有则回退到有前缀的键名
            String url = properties.getProperty("url", properties.getProperty("jdbc.url"));
            String username = properties.getProperty("username", properties.getProperty("jdbc.username"));
            String password = properties.getProperty("password", properties.getProperty("jdbc.password"));
            String driver = properties.getProperty("driver", properties.getProperty("jdbc.driver"));
            // 确保驱动已加载
            try {
                Class<?> driverClass = Class.forName(driver);
            } catch (ClassNotFoundException e) {
                logger.error("驱动类加载失败: {}", e.getMessage());
                throw new SQLException("数据库驱动未找到: " + driver, e);
            }

            // 添加连接超时参数
            String enhancedUrl = url;
            if (!url.contains("connectTimeout")) {
                enhancedUrl += (url.contains("?") ? "&" : "?") + "connectTimeout=10000&socketTimeout=10000";
            }

            // 记录连接前的时间
            long startTime = System.currentTimeMillis();
            conn = DriverManager.getConnection(enhancedUrl, username, password);
            long endTime = System.currentTimeMillis();
        } catch (SQLException e) {
            logger.error("获取数据库连接失败: {}", e.getMessage());
            throw e;
        }
        return conn;
    }

    /**
     * 关闭数据库连接
     * 
     * @param conn 数据库连接对象
     */
    public static void closeConnection(Connection conn) {
        if (conn != null) {
            try {
                if (!conn.isClosed()) {
                    conn.close();
                }
            } catch (SQLException e) {
                logger.error("关闭数据库连接失败: {}", e.getMessage());
            }
        }
    }

    /**
     * 测试数据库连接
     * 
     * @return 是否连接成功
     */
    public static boolean testConnection() {
        Connection conn = null;
        boolean success = false;
        try {
            conn = getConnection();
            success = conn != null && !conn.isClosed();
            if (success) {
                logger.info("数据库连接测试成功！");
            } else {
                logger.error("数据库连接测试失败！");
            }
        } catch (SQLException e) {
            logger.error("数据库连接测试异常: {}", e.getMessage());
        } finally {
            closeConnection(conn);
        }
        return success;
    }

    /**
     * 重新加载数据库配置
     * 当配置文件更新后，调用此方法重新加载配置
     * 
     * @return 是否加载成功
     */
    public static synchronized boolean reloadConfiguration() {
        try {
            if (environmentManager == null) {
                environmentManager = EnvironmentManager.getInstance();
            }

            String currentEnv = environmentManager.getCurrentEnvironment();
            logger.info("重新加载{}环境的数据库配置", currentEnv);

            // 使用EnvironmentManager重新加载当前环境的配置
            Properties newProperties = environmentManager.getCurrentDatabaseConfig();

            if (!newProperties.isEmpty()) {
                properties = newProperties;

                // 记录重新加载的配置信息
                if (properties != null && !properties.isEmpty()) {
                    String jdbcUrl = properties.getProperty("jdbc.url");
                    String username = properties.getProperty("jdbc.username");
                    logger.info("重新加载后 - 数据库URL: {}, 用户名: {}", jdbcUrl, username);
                }

                // 尝试重新注册驱动
                try {
                    String driver = properties.getProperty("driver", properties.getProperty("jdbc.driver"));
                    Class.forName(driver);
                    logger.info("成功重新注册JDBC驱动: {}", driver);
                } catch (ClassNotFoundException e) {
                    logger.error("无法加载JDBC驱动: {}", e.getMessage());
                }

                logger.info("{}环境的数据库配置重新加载成功", currentEnv);
                return true;
            } else {
                logger.error("加载当前环境的数据库配置失败");
                // 尝试加载默认配置作为后备
                try (InputStream input = DatabaseUtil.class.getClassLoader()
                        .getResourceAsStream("database.properties")) {
                    if (input != null) {
                        Properties defaultProperties = new Properties();
                        defaultProperties.load(input);
                        properties = defaultProperties;
                        logger.info("成功加载默认数据库配置文件作为后备");
                        return true;
                    }
                } catch (IOException e) {
                    logger.error("加载默认数据库配置文件失败: {}", e.getMessage());
                }
                return false;
            }
        } catch (Exception e) {
            logger.error("重新加载数据库配置失败: {}", e.getMessage());
            return false;
        }
    }
}